#ifndef _MAIN_C_
#define _MAIN_C_
/*********************************************************************************************************************/
#include "include/ca51f003_config.h"		
#include "include/ca51f003sfr.h"
#include "include/ca51f003xsfr.h"
#include "include/gpiodef_f003.h"
#include "include/system_clock.h"

#include <intrins.h>
#include "include/uart.h"
#include "include/delay.h"
#include "include/adc.h"
#include "include/Beep.h"

#include "include/spi.h"
#include "include/zkrd522.h"
#include "include/iso14443a.h"
#include "include/rfid_interface.h"
#include "mifare.h"
#include "desfire.h"

//TMCON定义
#define TME(N)		(N<<7) 	//N=0-1
#define TMF				(1<<0) 
bit IE_EA;
#define UART_SIZE_BUF 256
const unsigned char addr = ADDR;

typedef struct 
{
	unsigned char  head;
	unsigned char  addr;
	unsigned char  command;
	unsigned char  length; //只记录data数据长度
	unsigned char  buf[UART_SIZE_BUF];
	unsigned char   tail;
	unsigned char   bcc;
}xdata uart_data;
uart_data uart_buffer;
static unsigned char uart_flag = 0;

//status 状态码，len数据域长度
void uart_moudleRx(unsigned char status,unsigned char len)
{
	#if DEBUG
    unsigned char i,temp=0;
	uart_printf("RX:%02x %02x %02x ",(int)uart_buffer.head,
		(int)uart_buffer.addr,(int)uart_buffer.command);
	uart_printf("%02x ",(int)status);
	uart_printf("%02x ",(int)len);
	temp ^= uart_buffer.head;
	temp ^= uart_buffer.addr;
	temp ^= uart_buffer.command;
	temp ^= status;
	temp ^= len;
	for(i=0;i<len;i++)
	{
		temp ^= uart_buffer.buf[i];
		uart_printf("%02x ",(int)uart_buffer.buf[i]);
	}
	temp ^= uart_buffer.tail;
	uart_printf("%02x %02x\r\n",(int)uart_buffer.tail,(int)temp);
	
	#else
	
	unsigned char i,temp=0;
	Uart2_PutChar(uart_buffer.head);
	Uart2_PutChar(uart_buffer.addr);
	Uart2_PutChar(uart_buffer.command);
	Uart2_PutChar(status);
	Uart2_PutChar(len);
	temp ^= uart_buffer.head;
	temp ^= uart_buffer.addr;
	temp ^= uart_buffer.command;
	temp ^= status;
	temp ^= len;
	for(i=0;i<len;i++)
	{
		temp ^= uart_buffer.buf[i];
		Uart2_PutChar(uart_buffer.buf[i]);
	}
	temp ^= uart_buffer.tail;
	Uart2_PutChar(uart_buffer.tail);
	Uart2_PutChar(temp);
    #endif
	
	
}



void uart_read_data()
{
	unsigned char data_temp;
	static unsigned char len=0,i,temp=0;
	if(uart_flag != 0xff)
	{
		if(uart2_rev.tail != uart2_rev.head)		//表示有数据待取
		{
			uart2_rev.tail++;
			uart2_rev.tail %= UART1_RX_BUF_SIZE;				
			data_temp=uart2_rx_buf[uart2_rev.tail];
			if(data_temp == 0xAA && uart_flag == 0)
			{
				uart_buffer.head = data_temp;
				uart_flag = 1;
			}
			else if(uart_flag == 1)
			{
				if(data_temp == addr)
				{
					uart_buffer.addr = data_temp;
					uart_flag = 2;
				}
				else
				{
					uart_moudleRx(0x21,0);
					uart_flag = 0;
					uart2_rev.tail = uart2_rev.head;//清零舍弃后面的数据
				}
			}
			else if(uart_flag == 2)
			{
				uart_buffer.command = data_temp;
				uart_flag = 3;
			}
			else if(uart_flag == 3)
			{
				uart_buffer.length = data_temp;
				uart_flag = 4;
				len = data_temp;
				i=0;
				if(len>UART_SIZE_BUF)
				{
					uart_moudleRx(0x22,0);
					uart_flag = 0;
					uart2_rev.tail = uart2_rev.head;//清零舍弃后面的数据
				}
			}
			else if(uart_flag == 4)
			{
				if(len>0)
				{
					uart_buffer.buf[i++] = data_temp;
					len --;
				}
				else
				{
					if(data_temp == 0xBB)
					{
						uart_buffer.tail = data_temp;
						uart_flag = 5;
					}
					else
					{
						uart_moudleRx(0x23,0);
						uart_flag = 0;
						uart2_rev.tail = uart2_rev.head;//清零舍弃后面的数据
					}
				}
			}
			else if(uart_flag == 5)
			{
					uart_buffer.bcc = data_temp;
					temp ^= uart_buffer.head;
					temp ^= uart_buffer.addr;
					temp ^= uart_buffer.command;
					temp ^= uart_buffer.length;
					for(i=0;i<uart_buffer.length;i++)
					{
						temp ^= uart_buffer.buf[i];
					}
					temp ^= uart_buffer.tail;
					if(temp != uart_buffer.bcc)
					{
						uart_moudleRx(0x24,0);
						uart_flag = 0;
						uart2_rev.tail = uart2_rev.head;//清零舍弃后面的数据
					}
					else
					{
						uart_flag = 0xff;
						uart2_rev.tail = uart2_rev.head;
					}
					temp = 0;
			}
		}
	}
}


uint8_t Read_uid(unsigned char *uid)
{
	unsigned char xdata cln,sak; 
	unsigned char xdata status;
	status = get_typeA_card(&cln,uid,&sak);
	if(status == MI_OK)
	{
		pcb_init();
	}
	else
	{
		uid[0] = 0x00;
		spi_write_reg(txcontrol_reg,0x00);//关场
		Delay_ms(100);
		spi_write_reg(txcontrol_reg,0x1b);//开场
		Delay_ms(100);
	}
	return status;
}


void Enter_Stop_Mode()
{
		I2CCON = 0;						//关闭I2C，否则无法关闭主时钟
		SWICON |= 0x01;				//关闭单线通信功能，否则无法关闭主时钟
		CKCON = 0x80;					//其他时钟关闭，IRCL时钟不关闭
		PWCON &= ~0x08;				//设置LDO进入低功率模式
		MECON |= (1<<6); 			//设置 FLASH 进入深度睡眠状态
		while(STPSTH|STPSTL); //如果有中断未响应,等待中断被响应
		IE_EA = EA; 					//保存全局中断使能位状态
		EA = 0;
		PCON |= 0x02;					//进入STOP模式，等待TMC中断唤醒
		_nop_();
		_nop_();
		_nop_();
		EA = IE_EA; 					//恢复原全局中断开关状态	
		PWCON |= 0x08;				//退出STOP模式后，把LDO设回高功率模式
}
	
void TMC_ISR (void) interrupt 13 	  
{
	if(TMCON & TMF)			//毫秒中断
	{
		TMCON |= TMF;	
	}
}	


void app_run()
{
		moudle_in buf;
		unsigned char idata uid[12],status,i,uid_flag = 0,len=0x00;
		int data da;
		unsigned char idata desfire_key[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
																						0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
																					};//des初始密钥
		unsigned char idata app_aid[3] = {0x00,0x00,0x00};
		unsigned char data new_key[16];//存放DES会话密钥
		uart_read_data();
		if(uart_flag == 0xff)
		{
			#if DEBUG
            uart_printf("TX:%02x %02x %02x %02x ",(int)uart_buffer.head,(int)uart_buffer.addr,
			(int)uart_buffer.command,(int)uart_buffer.length);
			for(i=0;i<uart_buffer.length;i++)
			{
				uart_printf("%02x ",(int)uart_buffer.buf[i]);
			}
			uart_printf("%02x %02x\r\n",(int)uart_buffer.tail,(int)uart_buffer.bcc);
            #endif
			
			uart_flag = 0;
			switch(uart_buffer.command)
			{
				case 0x01://读模块信息
				status = desfire_keyVer(uart_buffer.buf,new_key,0x00);
				if(status == 0x00)
				{
					status = des_moudle_in(&buf);
					if(status == 0x00)
					{
						memcpy(uart_buffer.buf,buf.moudle_hard,7);
						memcpy(&uart_buffer.buf[7],buf.moudle_soft,7);
						memcpy(&uart_buffer.buf[14],buf.moudle,14);
						len = 28;
					}
				}
				break;
				
				case 0x02: //创建一个应用以及一个普通文件不带备份机制
				status = des_select_app(app_aid);
				status = desfire_keyVer(uart_buffer.buf,new_key,0x00);
				if(status == 0x00)
				{
					status = des_create_app(&uart_buffer.buf[16],0x09,0x01);
					if(status != 0x00&&status != 0xde)
					{
					}
					else
					{
						//命令创建明文通信的文件
						des_select_app(&uart_buffer.buf[16]);
						status = desfire_keyVer(desfire_key,new_key,0x00);
						status = Create_Std_Backup_DataFile(0x00,uart_buffer.buf[19],&uart_buffer.buf[20]);
					}
				}
				break;
				
				case 0x00: //初始化卡片
				status = des_select_app(app_aid);
				if(status == 0x00)
				{
					status = desfire_keyVer(uart_buffer.buf,new_key,0x00);
					if(status == 0x00)
					{
						status = FormatPICC();
						if(status == 0x00)
						{
							status = ChangeKey(&uart_buffer.buf[16],new_key);
						}
					}
				}
				break;
				
				case 0x03://写文件
				status = des_select_app(&uart_buffer.buf[1]);
				if(status == 0x00)
				{
					status = desfire_keyVer(&uart_buffer.buf[4],new_key,0x00);
					if(0x00 == status )
					{
						status = GetFileSettings(uart_buffer.buf[20],&i);
						if(status == 0x00)
						{
								if(i!=0x02)
								{
									status = write_std_Linear(i,uart_buffer.buf[20],&uart_buffer.buf[21],&uart_buffer.buf[24],&uart_buffer.buf[27]);
								}
								else
								{
									status = Credit_Debit(uart_buffer.buf[20],uart_buffer.buf[0],&uart_buffer.buf[21]);
								}
								if(status == 0x00)
								{
									if(i!= 0x00)
									{
										status = CommitTransaction();
									}
								}
						}
					}
				}
				break;
				
				case 0x04://读文件
				status = des_select_app(&uart_buffer.buf[0]);
				if(status == 0x00)
				{
					status = desfire_keyVer(&uart_buffer.buf[3],new_key,0x00);
					if(status == 0x00)
					{
						status = GetFileSettings(uart_buffer.buf[19],&i);
						if(0x00 == status)
						{
							if(i!=0x02)
							{
								status = Read_Cord_Data(i,uart_buffer.buf[19],&uart_buffer.buf[20],&uart_buffer.buf[23],uart_buffer.command);
							}
							else
							{
								status = GetValue(uart_buffer.buf[19],&da);
							}
						}
					}
				}
				break;
				
				case 0x05://创建各种类型文件
				status = des_select_app(&uart_buffer.buf[0]);
				if(status == 0x00)
				{
					status = desfire_keyVer(&uart_buffer.buf[3],new_key,0x00);
					if(status == 0x00)
					{
						i = uart_buffer.buf[19];
						if(uart_buffer.buf[19] == 0x00||uart_buffer.buf[19] == 0x01)
						{
							status = 	Create_Std_Backup_DataFile(uart_buffer.buf[19],uart_buffer.buf[20],&uart_buffer.buf[21]);
						}
						else if(uart_buffer.buf[19] == 0x03||uart_buffer.buf[19] == 0x04)
						{
							status = Create_Cyclic_LinearRecordFile(uart_buffer.buf[19],uart_buffer.buf[20],&uart_buffer.buf[21],&uart_buffer.buf[24]);
						}
						else if(uart_buffer.buf[19] == 0x02)
						{
							status = CreateValueFile(uart_buffer.buf[20],&uart_buffer.buf[21],&uart_buffer.buf[25],&uart_buffer.buf[29]);
						}
					}
				}				
				break;
				
				case 0x06:
				status = DESFire_HALT();
				if(status !=0x00)
				{
					status = pcd_halt();
					spi_write_reg(txcontrol_reg,0x00);//关场
					Delay_ms(100);
					spi_write_reg(txcontrol_reg,0x1b);//开场
					Delay_ms(100);
				}
				break;
				
				case 0x07://uid
				uid_flag = 0;
				while(1)
				{
					uid_flag++;
					if(uid_flag<=3)
					{
						status = Read_uid(uid);//获取uid
						if(status == 0x00)
						{
							memcpy(uart_buffer.buf,uid,8);
							uart_buffer.command = 0x07;
							len = 8;
							break;
						}
					}
					else
					{
						break;
					}
				}
				break;
				
				case 0x0f: //ATS
				uid_flag = 0;
				while(1)
				{
					uid_flag++;
					if(uid_flag<=3)
					{
						status = DESFire_RATS(uart_buffer.buf,&uart_buffer.length);
						if(status == 0x00)
						{
							uart_buffer.command = 0x0f;
							len = uart_buffer.length;
							break;
						}
					}
					else
					{
						break;
					}
				}
				break;
				case 0x08: //单步功能选择
				status = des_select_app(uart_buffer.buf);
				break;
				
				case 0x09: //单步验证
				status = desfire_keyVer(uart_buffer.buf,new_key,0x00);
				break;
				
				case 0x0a://单步 写文件只可以写二进制文件
				status = GetFileSettings(uart_buffer.buf[1],&i);
				if(0x00 == status)
				{
					if(i!=0x02)
					{
						status = write_std_Linear(i,uart_buffer.buf[1],&uart_buffer.buf[2],&uart_buffer.buf[5],&uart_buffer.buf[8]);
					}
					else
					{
						status = Credit_Debit(uart_buffer.buf[1],uart_buffer.buf[0],&uart_buffer.buf[2]);
					}
					if(status == 0x00)
					{
						if(i!= 0x00)
						{
							status = CommitTransaction();
						}

					}
				}
				break;
				case 0x0b: //单步读文件只可以读二进制文件
				status = GetFileSettings(uart_buffer.buf[0],&i);
				if(status == 0x00)
				{
					if(i!=0x02)
					{
						status = Read_Cord_Data(i,uart_buffer.buf[0],&uart_buffer.buf[1],&uart_buffer.buf[4],uart_buffer.command);
					}
					else
					{
						status = GetValue(uart_buffer.buf[0],&da);
					}
				}
				break;
				case 0x0c://获取应用目录数量和id
				status = des_select_app(app_aid);
				status = desfire_keyVer(uart_buffer.buf,new_key,0x00);
				if(0x00 == status)
				{
					status = GetApplicationIDs(uart_buffer.buf,&uart_buffer.length);
					if(0x00 == status)
					{
						uart_buffer.buf[uart_buffer.length] = uart_buffer.length/3;
						len = uart_buffer.length+1;
					}
				}
				break;
				case 0xf0://数据透传,直接发送不包装成块形式
				status = desocd_transmission(&uart_buffer.length,uart_buffer.buf);
				if(status == 0x00)
				{
					len = uart_buffer.length;
				}
				break;
				
				case 0xff://数据透传,直接发送包装成块形式
				status = DES_transmission(&uart_buffer.length,uart_buffer.buf);
				if(status == 0x00)
				{
					len = uart_buffer.length;
				}
				break;
				
				case 0x0d://修改密钥
				status = des_select_app(uart_buffer.buf);
				if(status == 0x00)
				{
					status = desfire_keyVer(&uart_buffer.buf[3],new_key,0x00);
					if(status == 0x00)
					{
						status = ChangeKey(&uart_buffer.buf[19],new_key);
					}
				}
				break;
				case 0x0e://返回模块信息
				memcpy(uart_buffer.buf,"RD522V1.0",9);
				len = 9;
				break;
				default :status = 0xFe;break;
			}
			if(status != 0x00&&status != 0xaf)
			{
				if(status == 0x01)
				{
					uart_moudleRx(status,0);
					status = DESFire_HALT();
					i=0;
					while(i<10)
					{
						status = DES_SBLOCK();
						if(status == 0x00)
						{
							if(uart_buffer.command != 0x00&&uart_buffer.command != 0xf0&&uart_buffer.command != 0xff)
							{
								uart_flag = 0xff;
							}
							break;
						}
						i++;
					}
					if(status !=0x00)
					{
						status = pcd_halt();
						spi_write_reg(txcontrol_reg,0x00);//关场
						Delay_ms(100);
						spi_write_reg(txcontrol_reg,0x1b);//开场
						Delay_ms(100);
					}
					status = Read_uid(uid);
					status = DESFire_RATS(uart_buffer.buf,&uart_buffer.length);
				}
				else
				{
					//uart_printf("error\r\n");
				}
				
			}
			if(uart_buffer.command != 0x04&&uart_buffer.command != 0x0b)
			{
				uart_moudleRx(status,len);
			}
			//uart_printf("\r\n");
		}
}	



void test(void);
void test1(void);
void main(void)
{
#ifdef LVD_RST_ENABLE
	LVDCON = 0xE0;					//设置LVD复位电压为2V
#endif

#ifdef UART1_EN
	Uart1_Initial(UART1_BAUTRATE);
#endif

#ifdef UART2_EN
	Uart2_Initial(UART2_BAUTRATE);
#endif
	
	EA = 1;							//开全局中断

#ifdef PRINT_EN
	uart_printf("RFID Demo Code\r\n");
#endif
	//ADC_Init();
/**********配置LED引脚***************************************************************/	
//	P17F = OUTPUT;
//	P20F = OUTPUT;
/**********蜂鸣器初始化***************************************************************/	
//	Beep_Init();
/**********配置RD522 RST引脚*********************************************************/
	P14F = OUTPUT; 
	RD522_RST_PIN = 0;
	Delay_ms(10);
	RD522_RST_PIN = 1;
	Delay_ms(10);
 /**********SPI初始化***************************************************************/
	P11F = OUTPUT;
	RD522_EA_PIN = 1;
	P13F = OUTPUT;
	RD522_I2C_PIN = 0;
	spi_init();
	Delay_ms(10);
/**********TMC定时器配置***************************************************************/
//	CKCON |= ILCKE;	//使能IRCL时钟
//	TMCON = TME(1);	//TMC使能
//	TMSNU = 129;			//设置中断时间，中断时间 = TMSNU * 512 * Tircl
//	INT8EN =1;
	RD522_RST_PIN = 0;                     //RST拉高使能
	Delay_50us(24);	
	RD522_RST_PIN = 1;                     //RST拉高使能
	Delay_50us(24);	
	pcd_config('A');
	pcd_set_rate(RATE_106,14);
	Delay_ms(100);

	while(1)
	{
		app_run();
//		test1();
	}
}

#define DEBUG_SIZE 0


void test(void)
{
	unsigned char uid[12],cln,sak,data_temp;
	char status = -1;
	unsigned long int i=0,error = 0;;
	if(uart2_rev.tail != uart2_rev.head)		//表示有数据待取
	{
		uart2_rev.tail++;
		uart2_rev.tail %= UART1_RX_BUF_SIZE;				
		data_temp=uart2_rx_buf[uart2_rev.tail];
		if(data_temp == 'A')//读卡下电
		{
			for(i = 0;i<DEBUG_SIZE+1;i++)
			{
				status = get_typeA_card(&cln,uid,&sak);
				if(status == MI_OK)
				{
					uart_printf("read uid ok!\r\n");
					pcb_init();
					status = DESFire_RATS(uart_buffer.buf,&uart_buffer.length);
					if(status == 0x00)
					{
						uart_printf("ATS OK!\r\n");
						status = DESFire_HALT();
						if(status !=0x00)
						{
							status = pcd_halt();
							spi_write_reg(txcontrol_reg,0x00);//关场
							Delay_ms(10);
							spi_write_reg(txcontrol_reg,0x1b);//开场
							Delay_ms(10);
						}
					}
					else
					{
						error++;
						uart_printf("ATS ERROR\r\n");
					}			
				}
				else
				{
					error++;
					uart_printf("error\r\n");
					spi_write_reg(txcontrol_reg,0x00);//关场
					Delay_ms(10);
					spi_write_reg(txcontrol_reg,0x1b);//开场
					Delay_ms(10);
				}
				
				if(i%100 == 0)
				{
					uart_printf("error = %ld size = %ld\r\n",error,i);
				}
			}
		}
		else if(data_temp == 'B')
		{
			status = get_typeA_card(&cln,uid,&sak);
			if(status == MI_OK)
			{
				uart_printf("read uid ok!\r\n");
				pcb_init();
				status = DESFire_RATS(uart_buffer.buf,&uart_buffer.length);
				if(status == 0x00)
				{
					uart_printf("ATS OK!\r\n");
					status = DESFire_HALT();
					if(status !=0x00)
					{
						status = pcd_halt();
						spi_write_reg(txcontrol_reg,0x00);//关场
						Delay_ms(10);
						spi_write_reg(txcontrol_reg,0x1b);//开场
						Delay_ms(10);
					}
				}
				else
				{
					uart_printf("ATS ERROR\r\n");
				}					
			}
			else
			{
				uart_printf("error\r\n");
				spi_write_reg(txcontrol_reg,0x00);//关场
				Delay_ms(10);
				spi_write_reg(txcontrol_reg,0x1b);//开场
				Delay_ms(10);
			}
		}
	}
}


void test1(void)
{
	unsigned char uid[12],cln,sak,data_temp;
	char status = -1;
	unsigned long int i=0,error = 0;;
	if(uart2_rev.tail != uart2_rev.head)		//表示有数据待取
	{
		uart2_rev.tail++;
		uart2_rev.tail %= UART1_RX_BUF_SIZE;				
		data_temp=uart2_rx_buf[uart2_rev.tail];
		Uart2_PutChar(data_temp);
		if(data_temp == 'A')//读卡下电
		{
			for(i = 0;i<DEBUG_SIZE+1;i++)
			{
				status = get_typeA_card(&cln,uid,&sak);
				if(status == MI_OK)
				{
					uart_printf("read uid ok!\r\n");
					pcb_init();
					status = pcd_halt();
				}
				else
				{
					error++;
					uart_printf("error\r\n");
					spi_write_reg(txcontrol_reg,0x00);//关场
					Delay_ms(10);
					spi_write_reg(txcontrol_reg,0x1b);//开场
					Delay_ms(10);
				}
			}
		}
		else if(data_temp == 'B')
		{
			status = get_typeA_card(&cln,uid,&sak);
			if(status == MI_OK)
			{
				uart_printf("read uid ok!\r\n");
				pcb_init();
				status = DESFire_RATS(uart_buffer.buf,&uart_buffer.length);
				if(status == 0x00)
				{
					uart_printf("ATS OK!\r\n");
					status = DESFire_HALT();
					if(status !=0x00)
					{
						status = pcd_halt();
						spi_write_reg(txcontrol_reg,0x00);//关场
						Delay_ms(10);
						spi_write_reg(txcontrol_reg,0x1b);//开场
						Delay_ms(10);
					}
				}
				else
				{
					uart_printf("ATS ERROR\r\n");
				}					
			}
			else
			{
				uart_printf("error\r\n");
				spi_write_reg(txcontrol_reg,0x00);//关场
				Delay_ms(10);
				spi_write_reg(txcontrol_reg,0x1b);//开场
				Delay_ms(10);
			}
		}
	}
}

#endif
